package xin.nick.demo;

import java.io.*;

/**
 * 多线程读取文本文件
 * 问题: 两个线程如何交替读出同一个文件并输出到控制台?
 * 1. 通过notify() 和 wait() 方法
 * 2. 使用 volatile 关键字
 * 3. 通过 CountDownLatch 工具类
 * 4. 通过 LockSupport 阻塞唤醒线程
 * 5. 通过 Lock ( ReentrantLock + Condition)
 */
public class MultiThreadReadText {

    //    private static String filePath = "D:\\temp\\text.txt";
    private static final String path = MultiThreadReadText.class.getResource("/").getPath();
    private static final String filePath = path + "text.txt";

    public static void main(String[] args) throws IOException {

    /** 基本的读取输出到控制台
     * File file = new File(filePath);
     * BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
     * String lineText;
     * while((lineText = bufferedReader.readLine()) != null) {
     *     System.out.println(lineText);
     * }
     * bufferedReader.close();
     */

        MyReader myReader = new MyReader(filePath);


        // 1.直接输出
//        new Reader1(myReader).start();
//        new Reader1(myReader).start();


        // 试一下新花样
        new Reader2(myReader).start();
        new Reader2(myReader).start();
    }

}

class MyReader {

    private BufferedReader bufferedReader;

    public MyReader(String filePath) throws FileNotFoundException {
        File file = new File(filePath);
        this.bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
    }

    public boolean print() {
        String lineText = null;
        try {
            if ((lineText = bufferedReader.readLine()) == null) return false;
        } catch (IOException e) {
            e.printStackTrace();
        }
        String threadName = Thread.currentThread().getName();
        System.out.println(threadName + "-" + lineText);
        return true;
    }
}

class Reader1 extends Thread {

    private MyReader myReader;

    public Reader1(MyReader myReader) {
        this.myReader = myReader;
    }

    @Override
    public void run() {
        while(myReader.print()) {

        }

    }
}

class Reader2 extends Thread {
    private MyReader myReader;

    public Reader2(MyReader myReader) {
        this.myReader = myReader;
    }

    @Override
    public synchronized void run() {
        while(true) {

            if(!myReader.print()) break;
//            try {
//                notify();
//                wait();
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
        }

    }
}